package com.example.himalaya.presenters;

import static com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl.PlayMode.*;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import androidx.annotation.Nullable;

import com.example.himalaya.data.XimalayaApi;
import com.example.himalaya.base.BaseApplication;
import com.example.himalaya.interfaces.IPlayerPresenter;
import com.example.himalaya.interfaces.IPlayerViewCallback;
import com.example.himalaya.utils.LogUtil;
import com.ximalaya.ting.android.opensdk.datatrasfer.IDataCallBack;
import com.ximalaya.ting.android.opensdk.model.PlayableModel;
import com.ximalaya.ting.android.opensdk.model.advertis.Advertis;
import com.ximalaya.ting.android.opensdk.model.advertis.AdvertisList;
import com.ximalaya.ting.android.opensdk.model.track.Track;
import com.ximalaya.ting.android.opensdk.model.track.TrackList;
import com.ximalaya.ting.android.opensdk.player.XmPlayerManager;
import com.ximalaya.ting.android.opensdk.player.advertis.IXmAdsStatusListener;
import com.ximalaya.ting.android.opensdk.player.constants.PlayerConstants;
import com.ximalaya.ting.android.opensdk.player.service.IXmPlayerStatusListener;
import com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl;
import com.ximalaya.ting.android.opensdk.player.service.XmPlayerException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PlayerPresenter implements IPlayerPresenter, IXmAdsStatusListener, IXmPlayerStatusListener {
    private static final String TAG = "PlayerPresenter";

    private final XmPlayerManager mXmPlayerManager;

    private List<Track> mCurrentPlayListTracks = new ArrayList<>();

    private List<IPlayerViewCallback> mPlayerViewCallbacks = new ArrayList<>();
    private Track mCurrentTrack;
    private int mCurrentPlayIndex=0;
    public static final int DEFAULT_PLAY_INDEX = 0;
    private final SharedPreferences mPlayModeSP;


    public static final String PLAY_MODE_SP_NAME="PlayMode";//SP的name
    public static final String PLAY_MODE_SP_KEY="currentPlayMode";//SP的key
    //SP的value
    public static int PLAY_MODE_SP_VALUE_LIST_LOOP_INT = 0;
    public static int PLAY_MODE_SP_VALUE_RANDOM_INT = 1;
    public static int PLAY_MODE_SP_VALUE_SINGLE_LOOP_INT = 2;

    private XmPlayListControl.PlayMode mCurrentPlayMode = PLAY_MODEL_LIST_LOOP;
    private boolean mPlayListIsReverse = false;
    private int mCurrentProgressPos=0;
    private int mProgressDuraton=0;

    private PlayerPresenter() {
        mXmPlayerManager = XmPlayerManager.getInstance(BaseApplication.getAppContext());
        mXmPlayerManager.addAdsStatusListener(this);//添加喜马拉雅广告状态监听器
        mXmPlayerManager.addPlayerStatusListener(this);//添加喜马拉雅播放器状态监听器
        //记录当前播放模式
        mPlayModeSP = BaseApplication.getAppContext().getSharedPreferences(PLAY_MODE_SP_NAME, Context.MODE_PRIVATE);
    }

    private static PlayerPresenter sPlayerPresenter;

    public static PlayerPresenter getPlayerPresenter() {
        if (sPlayerPresenter==null) {
            synchronized (PlayerPresenter.class) {
                if (sPlayerPresenter == null) {
                    sPlayerPresenter = new PlayerPresenter();
                }
            }
        }
        return sPlayerPresenter;
    }


    private boolean isPlayListSet = false;//播放列表是否设置
    /**
     * 设置播放列表
     * @param tracks 曲目列表
     * @param startIndex 播放列表中从第几首曲目开始
     */
    public void setPlayList(List<Track> tracks, int startIndex) {

        if (tracks != null&&tracks.size()>0) {
            mCurrentPlayListTracks.clear();
            mCurrentPlayListTracks.addAll(tracks);
        }

        if (mXmPlayerManager != null) {
            mXmPlayerManager.clearPlayCache();//清除之前的播放缓存，否则播放器播放曲目会混乱。
            mXmPlayerManager.setPlayList(mCurrentPlayListTracks, startIndex);
            isPlayListSet = true;
            mCurrentTrack = tracks.get(startIndex);
            mCurrentPlayIndex = startIndex;
        } else {
            LogUtil.d(TAG,"播放管理器为空");
        }

    }


    @Override
    public void registerViewCallBack(IPlayerViewCallback iPlayerViewCallback) {
        if (!mPlayerViewCallbacks.contains(iPlayerViewCallback)) {
            mPlayerViewCallbacks.add(iPlayerViewCallback);
        }
        getPlaylist();
        iPlayerViewCallback.onTrackUpdateUI(mCurrentTrack,mCurrentPlayIndex);
        Log.d(TAG, "registerViewCallBack: mCurrentPlayIndex-->"+mCurrentPlayIndex);
        //从SP中拿播放模式
        int modeInt = mPlayModeSP.getInt(PLAY_MODE_SP_KEY, PLAY_MODE_SP_VALUE_LIST_LOOP_INT);
        mCurrentPlayMode=getPlayModeByInt(modeInt);
        iPlayerViewCallback.onPlayModeChange(mCurrentPlayMode);

    }

    @Override
    public void unRegisterViewCallBack(IPlayerViewCallback iPlayerViewCallback) {
        if (mPlayerViewCallbacks != null) {
            mPlayerViewCallbacks.remove(iPlayerViewCallback);
        }
    }

    @Override
    public void play() {
        if (isPlayListSet) {
            int playerStatus = mXmPlayerManager.getPlayerStatus();
            LogUtil.d(TAG,"playerStatus -->"+playerStatus);
            if (mXmPlayerManager != null) {
                mXmPlayerManager.play();
            }
        }
    }

    @Override
    public void pause() {
        if (isPlayListSet) {
            if (mXmPlayerManager != null) {
                mXmPlayerManager.pause();
            }
        }
    }

    @Override
    public void stop() {

    }

    @Override
    public void playPre() {
        if (isPlayListSet) {
            if (mXmPlayerManager != null) {
                mXmPlayerManager.playPre();
            }
        }
    }

    @Override
    public void playNext() {
        if (isPlayListSet) {
            if (mXmPlayerManager != null) {
                mXmPlayerManager.playNext();
            }
        }
    }

    @Override
    public void switchPlayMode(XmPlayListControl.PlayMode mode) {
        if (mXmPlayerManager != null) {
            mCurrentPlayMode = mode;
            mXmPlayerManager.setPlayMode(mode);
            if (mPlayerViewCallbacks != null) {
                for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                    playerViewCallback.onPlayModeChange(mode);
                }
            }
            //播放模式保存到SP中
            SharedPreferences.Editor edit = mPlayModeSP.edit();
            edit.putInt(PLAY_MODE_SP_KEY, getIntByPlayMode(mode));
            edit.commit();
        }
    }

    private int getIntByPlayMode(XmPlayListControl.PlayMode mode) {
        switch (mode) {
            case PLAY_MODEL_LIST_LOOP:
                return PLAY_MODE_SP_VALUE_LIST_LOOP_INT;
            case PLAY_MODEL_RANDOM:
                return PLAY_MODE_SP_VALUE_RANDOM_INT;
            case PLAY_MODEL_SINGLE_LOOP:
                return PLAY_MODE_SP_VALUE_SINGLE_LOOP_INT;
        }
        return PLAY_MODE_SP_VALUE_LIST_LOOP_INT;
    }

    private XmPlayListControl.PlayMode getPlayModeByInt(int modeInt) {
        switch (modeInt) {
            case 0:
                return PLAY_MODEL_LIST_LOOP;
            case 1:
                return PLAY_MODEL_RANDOM;
            case 2:
                return PLAY_MODEL_SINGLE_LOOP;
        }
        return PLAY_MODEL_LIST_LOOP;
    }

    /**
     * 判断是否有播放列表
     * @return
     */
    public boolean hasPlayList() {
        return isPlayListSet;
    }

    @Override
    public void getPlaylist() {
        if (mXmPlayerManager != null) {
//            List<Track> playList = mXmPlayerManager.getPlayList();
            if (mPlayerViewCallbacks != null) {
                for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                    playerViewCallback.onTrackListUI(mCurrentPlayListTracks);
                }
            }
        }



    }

    @Override
    public void playByListItemIndex(int index) {
        mXmPlayerManager.play(index);
    }

    @Override
    public void seekTo(int progress) {
        if (mXmPlayerManager != null) {
            mXmPlayerManager.seekTo(progress);
        }
    }

    @Override
    public boolean isPlaying() {
        if (mXmPlayerManager != null) {
            //返回当前是否正在播放
            return mXmPlayerManager.isPlaying();
        } else {
            throw new NullPointerException();
        }
    }

    public int getCurrentProgressPos() {
        return mCurrentProgressPos;
    }

    public int getProgressDuraton() {
        return mProgressDuraton;
    }

    @Override
    public void reversePlayListOrder() {
        if (mXmPlayerManager != null) {
            Collections.reverse(mCurrentPlayListTracks);//把播放列表反转
            mPlayListIsReverse = !mPlayListIsReverse;
            //新的下表=总的内容个数-1-当前下标
            mCurrentPlayIndex = mCurrentPlayListTracks.size() - 1 - mCurrentPlayIndex;
            mXmPlayerManager.setPlayList(mCurrentPlayListTracks,mCurrentPlayIndex);

            //更新UI
            mCurrentTrack = (Track) mXmPlayerManager.getCurrSound();
            if (mPlayerViewCallbacks != null) {
                for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                    playerViewCallback.onTrackListUI(mCurrentPlayListTracks);
                    playerViewCallback.onTrackUpdateUI(mCurrentTrack,mCurrentPlayIndex);
                    playerViewCallback.onUpdatePlayListOrder(mPlayListIsReverse);
                }
            }
        }
    }

    @Override
    public void playByAlbumId(long id) {
        XimalayaApi ximalayaApi = XimalayaApi.getmXimalayaApi();
        ximalayaApi.getAlbumDetail(id, 1, new IDataCallBack<TrackList>() {
            @Override
            public void onSuccess(@Nullable TrackList trackList) {
                List<Track> tracks = trackList.getTracks();
                if (tracks != null && tracks.size() > 0) {
                        mCurrentPlayListTracks.clear();
                        mCurrentPlayListTracks.addAll(tracks);
                }
                if (mXmPlayerManager != null) {
                    mXmPlayerManager.clearPlayCache();//清除之前的播放缓存，否则播放器播放曲目会混乱。
                    mXmPlayerManager.setPlayList(mCurrentPlayListTracks, DEFAULT_PLAY_INDEX);
                    isPlayListSet = true;
                    mCurrentTrack = tracks.get(DEFAULT_PLAY_INDEX);
                    mCurrentPlayIndex = DEFAULT_PLAY_INDEX;
                } else {
                    LogUtil.d(TAG,"播放管理器为空");
                }
            }

            @Override
            public void onError(int i, String s) {

            }
        });
    }


    //===================广告相关的回调 start==========================
    @Override
    public void onStartGetAdsInfo() {
        LogUtil.d(TAG,"开始获取广告物料");

    }

    @Override
    public void onGetAdsInfo(AdvertisList advertisList) {
        LogUtil.d(TAG,"获取广告物料成功");
    }

    @Override
    public void onAdsStartBuffering() {
        LogUtil.d(TAG,"广告开始缓冲");
        if (mPlayerViewCallbacks != null) {
            for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                playerViewCallback.onAdLoading();
            }
        }
    }

    @Override
    public void onAdsStopBuffering() {
        LogUtil.d(TAG,"广告结束缓冲");
    }

    /**
     *
     * @param ad 当前播放广告
     * @param position 当前播放的广告在广告列表中的索引
     */
    @Override
    public void onStartPlayAds(Advertis ad, int position) {
        LogUtil.d(TAG,"开始播放广告");

    }

    @Override
    public void onCompletePlayAds() {
        LogUtil.d(TAG,"广告播放完毕");
    }

    /**
     *
     * @param what 错误类型
     * @param extra  错误的额外信息
     */
    @Override
    public void onError(int what, int extra) {
        LogUtil.d(TAG,"播放广告错误");
        LogUtil.d(TAG, "错误类型 -->" + what);
        LogUtil.d(TAG, "错误的额外信息 -->" + extra);
    }
//===================广告相关的回调 end==========================





//===================播放器相关的回调 start==========================
    @Override
    public void onPlayStart() {
        LogUtil.d(TAG,"开始播放");
        if (mPlayerViewCallbacks != null) {
            for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                playerViewCallback.onPlayStart();
            }
        }
    }

    @Override
    public void onPlayPause() {
        LogUtil.d(TAG,"暂停播放");
        if (mPlayerViewCallbacks != null) {
            for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                playerViewCallback.onPlayPause();
            }
        }
    }

    @Override
    public void onPlayStop() {
        LogUtil.d(TAG,"停止播放");
        if (mPlayerViewCallbacks != null) {
            for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                playerViewCallback.onPlayStop();
            }
        }
    }

    @Override
    public void onSoundPlayComplete() {
        LogUtil.d(TAG,"播放完成");
    }

    @Override
    public void onSoundPrepared() {
        LogUtil.d(TAG,"播放器准备完毕");
        mXmPlayerManager.setPlayMode(mCurrentPlayMode);//设置播放模式
        if (mXmPlayerManager.getPlayerStatus()== PlayerConstants.STATE_PREPARED) {
            //播放器准备完毕，去播放
            mXmPlayerManager.play();
        }
    }

    /**
     * 切歌，getKind()获取内容类型
     * 请通过model中的kind字段来判断是track、radio和schedule;
     * 上一首的播放时间请通过lastPlayedMills字段来获取;
     * @param lastModel 上一首播放内容，可能为空
     * @param curModel 当前播放内容
     */
    @Override
    public void onSoundSwitch(PlayableModel lastModel, PlayableModel curModel) {
        LogUtil.d(TAG,"切歌");
        if (lastModel != null) {
            LogUtil.d(TAG,"lastModel -->"+lastModel.getKind());
        }

        if (curModel != null) {
            LogUtil.d(TAG,"curModel -->"+curModel.getKind());
        }


        mCurrentPlayIndex = mXmPlayerManager.getCurrentIndex();
        if (curModel instanceof Track) {
            mCurrentTrack = (Track) curModel;
            //保存播放记录
            HistoryPresenter historyPresenter = HistoryPresenter.getHistoryPresenter();
            historyPresenter.addHistory(mCurrentTrack);
            //更新UI
            if (mPlayerViewCallbacks != null) {
                for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                    playerViewCallback.onTrackUpdateUI(mCurrentTrack,mCurrentPlayIndex);
                }
            }
        }
    }

    @Override
    public void onBufferingStart() {
        LogUtil.d(TAG,"开始缓冲");
    }

    @Override
    public void onBufferingStop() {
        LogUtil.d(TAG,"结束缓冲");
    }

    @Override
    public void onBufferProgress(int percent) {
        LogUtil.d(TAG,"缓冲进度回调 -->"+percent);
    }

    /**
     * 播放进度回调
     * @param currentPos 当前进度，单位是毫秒
     * @param duration 总时长，单位是毫秒
     */
    @Override
    public void onPlayProgress(int currentPos, int duration) {
        this.mCurrentProgressPos = currentPos;
        this.mProgressDuraton = duration;
//        LogUtil.d(TAG,"-----播放进度回调-----");
//        LogUtil.d(TAG,"当前位置 -->"+currentPos);
//        LogUtil.d(TAG,"总时长 -->"+duration);
        if (mPlayerViewCallbacks != null) {
            for (IPlayerViewCallback playerViewCallback : mPlayerViewCallbacks) {
                playerViewCallback.onProgressChange(currentPos,duration);
            }
        }
    }

    /**
     * 这里面返回的错误code没有参考价值,如果配置正确但是却播放不了,最大的可能就是网络导致的.
     * 请注意log中的"PlayError"字段 ,如果responseCode != 200 说明就是网络问题,请换个网络重试下看看
     * code=612 表示没有播放地址
     * @param e
     * @return
     */
    @Override
    public boolean onError(XmPlayerException e) {
        LogUtil.d(TAG,"播放器错误");
        LogUtil.d(TAG,"播放器异常 -->"+e);
        return false;
    }


//===================播放器相关的回调 end==========================


}
